#!/bin/bash


Install_Path=/Library/Printers/DNP

OSX=$(sw_vers -productVersion) &&
 OSX_VERS=(${OSX//./ }) &&
 echo "Mac OS X version $OSX (major=${OSX_VERS[0]}; Minor=${OSX_VERS[1]}; micro=${OSX_VERS[2]})"


update_ppds () {
# +++ Load new CUPS PPDs for any existing queues +++

Xlpstat=/usr/bin/lpstat
Xlpadmin=/usr/sbin/lpadmin
Xlp=/usr/bin/lp

if [ ! -x $Xlpstat ] ; then 
exit 0
fi

# scan for existing queues...
echo -n "Checking for existing printer queues to update ... "

# set the CUPS ppd directory variable
CUPS_PPD_DIR=/etc/cups/ppd
MODEL_PPD_DIR="/Library/Printers/PPDs/Contents/Resources"

#set the match key for our models (regex)
KEY_1="Dai Nippon Printing "

# get the queue names and PPD file names from the existing queues
i=0
eval $(find "${CUPS_PPD_DIR}" -name '*.ppd' -execdir awk  -v key1="${KEY_1}" '/^[*]NickName/ && ($0 ~ key1) {qn=FILENAME;next};/^[*]PCFileName/ {n=split($0,a,"\"");pcfl=sprintf("\"%s\"\n",a[2]);next};END {if("" != qn && "" != pcfl){printf "QUEUE_LIST[$((i))]=%s;PCFileName[$((i++))]=%s;",qn,pcfl}}' '{}' ';')

# just exit if there are no queues
echo "found ${#QUEUE_LIST[@]} queues."
((0 < ${#QUEUE_LIST[@]} )) || return 0


# make sure that the cupsd scheduler is running since it may have just been sent SIGHUP
  delay=1
  while [ "`$Xlpstat -r 2>&1`" != "scheduler is running" -a $delay -lt 10 ]
  do
     sleep $delay
     echo waiting $delay seconds for scheduler
     ((delay*=2))
  done

# update each queue with the new PPD...
echo "Attempting to update the following printer queues:"
i=0
j=0
for NAME in "${QUEUE_LIST[@]%.ppd}"
do
IFS=$'\n'
PPD=
PPD_NAME="${PCFileName[$((i++))]}"
  test "${PPD_NAME}" &&
   PPD=($(find "${MODEL_PPD_DIR}" -name "${PPD_NAME}.gz" -o -name "${PPD_NAME}"))
echo -en " $i) $NAME with PPD \"$PPD\" ... "

# make sure that the PPD file is readable
   if test -r "${PPD}"; then
# actually set the queue to use the new PPD
     RESULT=$($Xlpadmin -p $NAME -P "${PPD}" 2>&1)
     test "${RESULT}" &&
         echo -e "FAILED!\n\t(${RESULT})" || {
         echo "success."
         ((j++))
         echo -e '#CUPS-COMMAND\nAutoConfigure\n'|$Xlp -d ${NAME} -- - >/dev/null

#        echo -e '#CUPS-COMMAND\nReportLevels'|$Xlp -t "Checking Printer Status ..." -d ${NAME} -- - >/dev/null
         }
   else
      echo "Queue $NAME failed to be updated because the The PPD $PPD was not readable!"
   fi
done
echo "Successfully updated $j of ${#QUEUE_LIST[@]} printer queues."
}
update_ppds

##############################################################
((EUID == 0)) || { echo "$EUID is not 0 ($UID)"; exit 0; }

/usr/sbin/chown -R 0:0 "${MODEL_PPD_DIR}"
exit
###############################################################
################################################################################
##### awk programs #############################################################
################################################################################

### `awk__match_DM_return' parses the return string from an applescript dialog
### usage notes: `str' must be passed to awk as a variable indicating the
### desired result.
### example: Button_Clicked=$(printf "%s\n" ${TheResult}| awk -v 'str=button returned:' \
### "${awk__match_DM_return}")

awk__match_DM_return='{lenstr=length(str);str=str "[^,]*";if (match($0,str)) print substr($0,RSTART+lenstr,RLENGTH-lenstr);}'

##### Usage for do_dialog_with_editable_string ()
##### up to 3 arguments; argument 1 is the icon to use: 0=Stop, 1=Note, 2=Warning
##### argument 2 determines if there is a beep or not; use `beep' for beep or `no' for no beep (default is no beep)
##### argument 3 specifies the `giving up' time; never specify a value greater than 120
##### the variable DialogMessageDoInfo and the array info_dialog_button_list must
##### be set before calling the function. After calling the function the variable
##### The function will return immediately and no results will be obtained
##### example: do_custom_info_dialog 0 no 15
##### would display a dialog with the 'stop' icon, doesn't beep, and gives up after 15 seconds
##### example: do_custom_info_dialog 2 beep
##### would display a dialog that shows the 'warning' icon and beeps, and gives up after (default) 90 seconds
parse_osascript_result () {
    local reply=$@
    local main=${reply%, gave up:*}
    gaveup=${reply#$main}
    gaveup=${gaveup#, gave up:}
    local main2=${main%, button returned:*}
    local buttonR=${main#$main2}
    Button_Clicked=${buttonR#, button returned:}
    echo ${main2#text returned:}
}
g_scriptable_app="SystemUIServer"
do_dialog_with_editable_string () {
trap return INT
[ -x "${Script_App:=$(which osascript)}" ] || return 1

local msg="Enter a message"
local icon beep
local -i the_icon=
for opt in "$@";do
    case "${opt}" in
        msg=*|message=*)
        msg=${opt#*=}
        ;;
        beep=*)
        beep=${opt#*=}
        beep=${beep#[Nn][Oo]}
        ;;
        icon=*)
        the_icon=${opt#*=}
        icon=${the_icon}
        ;;
    esac
done
local -a buttons=("${info_dialog_button_list[@]:-OK}")
local -i defaultButton=${#buttons[@]}
((3 < defaultButton)) && { echo error using script -- too many buttons; return 1; }
(( 0 <= icon && 3 > icon)) || icon=2
local TheScript=`cat <<EndMark
${beep:+beep}
set AppleScript's text item delimiters to "\n"
set buttonList to every text item of "${buttons[@]}"
tell application "${g_scriptable_app}"
activate
display dialog "${msg}"  default answer "${DM_DefaultAnswer}" ${icon:+with icon} ${icon} buttons buttonList default button ${defaultButton:-1} giving up after 90
end tell
EndMark`

Button_Clicked=
until test "${Button_Clicked}" ;do
    local result=$("${Script_App}" <<<"${TheScript}") &&
    parse_osascript_result "${result}"
    echo "${result}"
    break
done
}

###############################################################
# add the advanced item to the AddPrinter.app toolbar
d_domain=com.apple.print.add
d_key="NSToolbar Configuration com.apple.print.add.toolbar"
dict_key='TB Item Identifiers'
adv_id='com.apple.print.pbm.advanced'

awk_prog1="BEGIN {
 adv=\"${adv_id}\";
 key=\"${dict_key}\";
 i=0;
};"'
 $0 ~ key  {
 h=1;while(getline){
  if(match($0,adv)){
   hasAdv=1
  };
  gsub("^[ \t]+","");
  gsub(/"/,"",$0);
  n=split($0,a,",");
  if (1 <n){
   item[i++]=a[1]
  }else {
   item[i++]=$0;
   next
  }
 }
};
END {
if(!hasAdv){
 if (0 == i){
  n=split("pbm.uber pbm.fax pbm.ip pbm.smb pbm.bluetooth pbm.appletalk add.moreprinters pbm.advanced add.search",defaultItems);
  while(i<n) {
   item[i]="com.apple.print." defaultItems[i+1]
   i++;
  }
#uber fax ip smb bluetooth appletalk moreprinters NSToolbarFlexibleSpaceItem com.apple.print.pbm.advanced search
 } else {
  item[i]=item[i-1];
  item[i-1]=adv;
  i++;
 }
 printf "<array>";
 for(j=0;j<i;j++){
  printf "<string>%s</string>",item[j]
 };
 print "</array>"
 }
}'

# need to write defaults as sudo user
users=($(dscl . list /users UniqueID|awk '{if($NF > 500)print $1}'))
for u in "${users[@]}";do
  tbitems=$(sudo -u $u defaults read "${d_domain}" "${d_key}" |awk "${awk_prog1}")
  test "${tbitems}" || continue
  PID=$(sudo -u $u ps xww|awk '/Contents\/MacOS\/[A]ddPrinter/ {print $1}')
  test "${PID}" && kill -TERM $PID
  sudo -u $u defaults write "${d_domain}" "${d_key}" -dict-add "${dict_key}" "${tbitems}"
done
exit 0
